//
//  Copyright 2015 XiaoJSoft Studio.
//  Copyright 2015 Harbin Institute of Technology(HIT), Software Engineering Department.
//
//  Use of this source code is governed by a proprietary license. You can not read, change or
//  redistribute this source code unless you have a written authorization from the copyright
//  holder listed above.
//

#include "emit.h"
#include "codec.h"
#include "text_file.h"
#include <string>
#include <vector>

namespace ui {
namespace compiler {

Emit::Emit() {
    this->m_CSSURLs.clear();
    this->m_Scripts.clear();
    this->m_ScriptIsFile.clear();
}

Emit::~Emit() {
    //  Dummy.
}

void Emit::addScriptFile(const std::string &script_url) {
    this->m_Scripts.push_back(script_url);
    this->m_ScriptIsFile.push_back(true);
}

void Emit::addScriptText(const std::string &script_text) {
    this->m_Scripts.push_back(script_text);
    this->m_ScriptIsFile.push_back(false);
}

void Emit::addCSSFile(const std::string &css_url) {
    this->m_CSSURLs.push_back(css_url);
}

bool Emit::getCode(std::string &output) {
    std::string code = "<!DOCTYPE html>\n";

    //  Create 'ADD_LINE' macro for emitting.
#define ADD_LINE(_arg_line_) {\
    code += (_arg_line_);\
    code += "\n";\
}

    //  Emit the header.
    ADD_LINE("<html>");
    ADD_LINE("    <head>");
    ADD_LINE("        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + std::string(UIJS_COMPILER_WEBPAGE_CODEC) + "\" />\n");

    //  Emit package scripts.
    for (unsigned int i = 0; i < this->m_Scripts.size(); ++i) {
        std::string script_text;

        //  Get the script.
        if (this->m_ScriptIsFile[i]) {
            if (!textFileRead(this->m_Scripts[i], script_text)) {
                return false;
            }
        } else {
            script_text = this->m_Scripts[i];
        }

        //  Emit the script.
        if (script_text.length() != 0) {
            ADD_LINE("        <script type=\"text/xjdesktop-script\">");
            ADD_LINE(script_text);
            ADD_LINE("        </script>");
        }
    }

    //  Get the loader script from resources.
    std::string loader_script;
    if (!textFileRead(":/loader.js", loader_script)) {
        return false;
    }

    //  Emit the loader script.
    ADD_LINE("        <script type=\"text/javascript\">");
    ADD_LINE(loader_script);
    ADD_LINE("        </script>");

    //  Emit CSS files.
    for (std::vector<std::string>::iterator css_url = this->m_CSSURLs.begin(); css_url != this->m_CSSURLs.end(); ++css_url) {
        ADD_LINE("        <link rel=\"stylesheet\" type=\"text/css\" href=\"" + (*css_url) + "\">");
    }

    //  Emit the tail.
    ADD_LINE("    </head>");
    ADD_LINE("    <body>");
    ADD_LINE("    </body>");
    ADD_LINE("</html>");

    //  Undefine the 'ADD_LINE' to clean up.
#undef ADD_LINE

    //  Set output.
    output = code;

    return true;
}

}  //  namespace compiler
}  //  namespace ui
